package com.gukun.springboot.tdengine.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gukun.springboot.tdengine.dao.TDEngineDao;
import com.gukun.springboot.tdengine.domain.common.CommonResult;
import com.gukun.springboot.tdengine.domain.common.PageParam;
import com.gukun.springboot.tdengine.domain.common.PageResult;
import com.gukun.springboot.tdengine.domain.enums.TagType;
import com.gukun.springboot.tdengine.domain.exception.util.ServiceExceptionUtil;
import com.gukun.springboot.tdengine.dto.*;
import com.gukun.springboot.tdengine.enums.TdengineDataType;
import com.gukun.springboot.tdengine.enums.TdengineEnums;
import com.gukun.springboot.tdengine.pojo.*;
import com.gukun.springboot.tdengine.service.writeplant.FastWriteTagData;
import com.gukun.springboot.tdengine.service.writeplant.MockDataSource;
import com.gukun.springboot.tdengine.service.writeplant.TDConfigDto;
import com.gukun.springboot.tdengine.util.DateUtils;
import com.gukun.springboot.tdengine.util.SyzTypeUtils;
import com.gukun.springboot.tdengine.util.TypeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.*;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 使用原生JDBC进行数据处理
 * 在插入等功能上，减少sql损耗
 */

@Service
public class TDEngineService {
    //    private ScheduledExecutorService scheduleAtFixedRate = Executors.newScheduledThreadPool(1);
    //缓存，存储写入任务的执行情况, key 代表具体写入任务,名称是数据库名称_表前缀,value是具体的fastWriteTagData
    private ConcurrentHashMap<String, FastWriteTagData> fastWriteCache = new ConcurrentHashMap<>();
    private ConcurrentHashMap<String, Timer> scheduledFutureCache = new ConcurrentHashMap<>();

    private String cacheKey = "tdCache";

//    private static final Logger logger = LoggerFactory.getLogger(TDEngineService.class);

    private static final org.apache.log4j.Logger logger = LogManager.getLogger(TDEngineService.class);

    private Map<String, TDEngineDao> tdEngineDaoMap = new ConcurrentHashMap<>();

    public TDEngineDao getTDEngineDao(DBConfig dbConfig) {
        return getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(), dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
    }

    /**
     * 获取TDEngineDao
     *
     * @param host
     * @param port
     * @param user
     * @param password
     * @param dbName
     * @return
     */
    public TDEngineDao getTDEngineDao(String host, int port, String user, String password, String dbName) {
        String key = host + port + user + password;
        try {
            if (tdEngineDaoMap.containsKey(key)) {
                TDEngineDao tdEngineDao = tdEngineDaoMap.get(key);
                if (!tdEngineDao.getConnection().isValid(500)) {
                    //管理连接后移除
                    tdEngineDao.getConnection().close();
                    //如果当前连接不可用，就删除，重新创建一个
                    tdEngineDaoMap.remove(key);
                    tdEngineDao = createTdengineDao(host, port, user, password, dbName);
                    if (tdEngineDao != null) {
                        tdEngineDaoMap.put(key, tdEngineDao);
                    }
                }
                return tdEngineDao;
            } else {
                return createTdengineDao(host, port, user, password, dbName);
            }
        } catch (Exception e) {
            logger.error("获取TDEngineDao失败", e);
            return null;
        }
    }

    public TDEngineDao createTdengineDao(String host, int port, String user, String password, String dbName) throws Exception {
        String key = host + port + user + password;
        TDEngineDao tdEngineDao = new TDEngineDao();
        tdEngineDao.init(host, port, user, password, dbName);
        Connection connection = tdEngineDao.getConnection();
        if (connection != null && connection.isValid(500)) {
            tdEngineDaoMap.put(key, tdEngineDao);
            return tdEngineDao;
        }
        return null;
    }


    /**
     * 获取所有数据库
     *
     * @return List<String>
     */
    public List<String> showDatabases(String host, int port, String user, String password) throws Exception {
        TDEngineDao tdEngineDao = getTDEngineDao(host, port, user, password, "");
        if (tdEngineDao == null) {
            throw ServiceExceptionUtil.exception0(500, StrUtil.format("获取数据库失败，请检查数据库连接信息,{}:{}", host, port));
        }
        return tdEngineDao.showDatabases();
    }


    /**
     * 获取所有超级表
     *
     * @return List<String>
     */
    public List<String> showSTables(String host, int port, String user, String password, String dbName) {
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(host, port, user, password, "");
            tdEngineDao.useDb(dbName);
            return tdEngineDao.showSTables();
        } catch (Exception e) {
            logger.error("获取超级表失败", e);
        }

        return null;
    }


    /**
     * 获取所有数据库
     *
     * @return List<String>
     */
    public List<List<String>> executeSQL(String host, int port, String user, String password, String dbName, String sql) {
        TDEngineDao tdEngineDao = getTDEngineDao(host, port, user, password, "");
        try {
            tdEngineDao.useDb(dbName);
            return tdEngineDao.executeSQL(sql, 1000);
        } catch (SQLException e) {
            logger.error("执行sql失败", e);
        }

        return null;
    }

    /**
     * 根据超表获取所有表
     *
     * @return List<String>
     */
    public List<String> showTablesBySTable(String host, int port, String username, String password, String dbName, String stableName) {
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(host, port, username, password, dbName);
            tdEngineDao.useDb(dbName);
            return tdEngineDao.showTablesBySTable(stableName);
        } catch (Exception e) {
            logger.error("获取表失败", e);
        }

        return null;
    }

    /**
     * 获取所有表
     *
     * @return List<String>
     */
    public List<String> showTables(String host, int port, String username, String password, String dbName, String filter) {
        TDEngineDao tdEngineDao = getTDEngineDao(host, port, username, password, dbName);
        try {
            tdEngineDao.useDb(dbName);
            return tdEngineDao.showTables(filter);
        } catch (SQLException e) {
            logger.error("获取表失败", e);
        }
        return null;
    }

    public PageResult<TableDto> getTableByPage(DBConfig dbConfig, String filterName, PageParam page, String superTableName, boolean isSuperTable, String likeDesc, boolean needLastValue) {
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig);
        PageResult<TableDto> result = null;
        try {
            if (isSuperTable) {
                result = tdEngineDao.getStableByPage(filterName, dbConfig.getDbName(), page.getPageSize(), page.getPageNo());
            } else {
                result = tdEngineDao.getTableByPage(filterName, likeDesc, dbConfig.getDbName(), superTableName, page.getPageSize(), page.getPageNo(), needLastValue);
            }
        } catch (Exception e) {
            logger.error("分页查询表格报错：", e);
            return new PageResult<>(new ArrayList<>(), 0L);
        }
        return result;
    }

    /**
     * 获取分页的TDEngine历史数据
     *
     * @param queryHisDataInput 查询历史数据的参数
     * @return PageResult<TagHisData>
     */
    public PageResult<TagData> queryHistoryData(QueryHisDataInput queryHisDataInput) {
        DBConfig dbConfig = queryHisDataInput.getDbConfig();
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        try {
            tdEngineDao.useDb(queryHisDataInput.getDbConfig().getDbName());
            return tdEngineDao.queryHistoryData(queryHisDataInput);
        } catch (Exception e) {
            logger.error("查询历史数据失败", e);
        }

        return null;
    }

    /**
     * 初始化TDengine数据库
     *
     * @param tDengineConfigDto
     * @return
     */
    public CommonResult<String> initTdengineDatbase(TDengineConfigDto tDengineConfigDto) {
        TDEngineDao tdEngineDao = getTDEngineDao(tDengineConfigDto.getHost(), tDengineConfigDto.getPort(), tDengineConfigDto.getUsername(), tDengineConfigDto.getPassword(), tDengineConfigDto.getName());
        try {
            if (Objects.isNull(tDengineConfigDto.getHost())) {
                return CommonResult.error(500, "数据库ip不能为空");
            }
            if (Objects.isNull(tDengineConfigDto.getPort())) {
                return CommonResult.error(500, "数据库端口号不能为空");
            }
            if (Objects.isNull(tDengineConfigDto.getName())) {
                return CommonResult.error(500, "数据库名称不能为空");
            }
            if (tDengineConfigDto.getIsDelete()) {
                try {
                    tdEngineDao.dropDatabase(tDengineConfigDto.getName());
                } catch (Exception e) {
                    return CommonResult.error(500, "初始化数据库失败，请联系管理员");
                }
            }
            tdEngineDao.createDatabase(tDengineConfigDto.getName(), tDengineConfigDto.getVgroups(), tDengineConfigDto.getBuffer(), tDengineConfigDto.getCachesize(), tDengineConfigDto.getCachemodel());
            return CommonResult.success("初始化数据库成功");
        } catch (SQLException e) {
            return CommonResult.error(500, "初始化数据库失败，请联系管理员");
        }
    }

    /**
     * 执行建表
     *
     * @param createTableDto
     * @return
     */
    public CommonResult<String> createTdengineTables(CreateTableDto createTableDto) {

        try {
            TDengineConfigDto tDengineConfigDto = createTableDto.gettDengineConfigDto();
            if (Objects.isNull(tDengineConfigDto.getHost())) {
                return CommonResult.error(500, "数据库ip不能为空");
            }
            if (Objects.isNull(tDengineConfigDto.getPort())) {
                return CommonResult.error(500, "数据库端口号不能为空");
            }
            if (Objects.isNull(tDengineConfigDto.getName())) {
                return CommonResult.error(500, "数据库名称不能为空");
            }
            TDEngineDao tdEngineDao = getTDEngineDao(tDengineConfigDto.getHost(), tDengineConfigDto.getPort(), tDengineConfigDto.getUsername(), tDengineConfigDto.getPassword(), tDengineConfigDto.getName());
            //新建四张超级表
            tdEngineDao.useDb(tDengineConfigDto.getName());
            tdEngineDao.createSupTableAll();
            //为四张超表下面新建对应类型的表
            //分别为 float、double、int、bool生成对应的表
            int index = createTableDto.getIndex();
            List<TagInfo> tagList = new ArrayList<>(createTableDto.getCount());
            int floatTableCount = createTableDto.getFloatTableCount();
            for (int i = 0; i < floatTableCount; i++) {
                addTagIntoList(createTableDto, tagList, TagType.FLOAT, index);
                index++;
            }

            int doubleTableCount = createTableDto.getDoubleTableCount();
            for (int i = 0; i < doubleTableCount; i++) {
                addTagIntoList(createTableDto, tagList, TagType.DOUBLE, index);
                index++;
            }


            int intTableCount = createTableDto.getIntTableCount();
            for (int i = 0; i < intTableCount; i++) {
                addTagIntoList(createTableDto, tagList, TagType.INT, index);
                index++;
            }

            int boolTableCount = createTableDto.getBoolTableCount();
            for (int i = 0; i < boolTableCount; i++) {
                addTagIntoList(createTableDto, tagList, TagType.BOOL, index);
                index++;
            }

            if (CollectionUtil.isNotEmpty(tagList)) {
                tdEngineDao.useDb(tDengineConfigDto.getName());
                tdEngineDao.createTables(tagList);
            }
            return CommonResult.success("执行建表成功");
        } catch (SQLException e) {
            logger.error(e.getMessage(), e);
            return CommonResult.error(500, "执行建表失败，请联系管理员");
        }
    }

    private void addTagIntoList(CreateTableDto createTableDto, List<TagInfo> list, TagType tagType, int index) {
        TagInfo tagInfo = new TagInfo();
        tagInfo.setTagType(tagType);
        tagInfo.setTagName(createTableDto.getPrefix() + "" + index);
        tagInfo.setTagId((long) index);
        tagInfo.setTags(tagInfo.toString());
        list.add(tagInfo);
    }

    /**
     * 模拟数据写入
     *
     * @param writeRulesDTO
     * @return
     */
    public CommonResult<String> beginTDengineWrite(WriteRulesDto writeRulesDTO, String keyNameId, String taskName) {
        if (writeRulesDTO == null || writeRulesDTO.getCreateTableDto() == null || writeRulesDTO.getCreateTableDto().gettDengineConfigDto() == null) {
            return CommonResult.error(500, "数据库必要信息不能为空");
        }
        Date startDatetime = null;
        if (StringUtils.isNotBlank(writeRulesDTO.getStartDatetime())) {
            startDatetime = DateUtils.parseDateTime(writeRulesDTO.getStartDatetime());
        }

        Date endDatetime = null;
        if (StringUtils.isNotBlank(writeRulesDTO.getEndDatetime())) {
            endDatetime = DateUtils.parseDateTime(writeRulesDTO.getEndDatetime());
        }
        Integer period = writeRulesDTO.getPeriod();
//        模拟周期
        Integer mnPeriod = writeRulesDTO.getMnPeriod();
        //periodType: 0-固定周期  1-随机周期
        Integer periodType = writeRulesDTO.getPeriodType();
        FastWriteTagData writeTagData = null;
        try {
            TDConfigDto tdConfigDto = new TDConfigDto();
            fillTdConfigDTO(writeRulesDTO, tdConfigDto);
            MockDataSource mockData;
            switch (writeRulesDTO.getMockType()) {
                case 0:
                    mockData = new MockDataSource(tdConfigDto.getTablePre()
                            , tdConfigDto.getTableIndex(), tdConfigDto.getTableCount()
                            , startDatetime, endDatetime, period, mnPeriod, periodType);
                    break;
                case 1:
                case 2:
                case 3:
                    mockData = new MockDataSource(tdConfigDto.getTablePre()
                            , tdConfigDto.getTableIndex()
                            , tdConfigDto.getTableCount()
                            , startDatetime, endDatetime, period, mnPeriod, periodType, writeRulesDTO.getMockType());
                    break;
                default:
                    return CommonResult.error(500, "无法匹配的数据模拟格式");
            }
            writeTagData = new FastWriteTagData(tdConfigDto, false, cacheKey + keyNameId);
            FastWriteTagData finalWriteTagData = writeTagData;
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    try {
                        List<String> lineList = mockData.next();
                        if (lineList != null) {
                            long d1 = System.currentTimeMillis();
                            for (String line : lineList) {
                                int queueId = getQueueId(line, tdConfigDto.getTablePre(), finalWriteTagData, cacheKey + keyNameId);
                                finalWriteTagData.getTaskQueues(cacheKey + keyNameId).get(queueId).put(line);
                            }
                            List<BlockingQueue<String>> list = finalWriteTagData.getTaskQueues(cacheKey + keyNameId);
                            while (!checkListIsEmpty(list)) {
                                Thread.sleep(20);
                            }
                            long d2 = System.currentTimeMillis();
                            logger.error("任务：" + taskName + ",执行耗时：" + (d2 - d1));
                        } else {
                            //历史数据写入完成后，需要主动关闭
                            try {
                                FastWriteTagData writeTagData2 = fastWriteCache.get(cacheKey + keyNameId);
                                if (writeTagData2 != null) {
                                    writeTagData2.stopAll();
                                    fastWriteCache.remove(cacheKey + keyNameId);
                                    Timer timer2 = scheduledFutureCache.get(cacheKey + keyNameId);
                                    if (timer2 != null) {
                                        timer2.cancel();
                                        timer2 = null;
                                        scheduledFutureCache.remove(cacheKey + keyNameId);
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                System.out.println("停止历史数据写入任务失败");
                            }
                        }
                    } catch (Exception e) {
                    }
                }
            };
            cn.hutool.core.date.DateTime dateTime = new DateTime();
            if (dateTime.millisecond() > 200) {
                try {
                    Thread.sleep(1000 - dateTime.millisecond());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
//            ScheduledFuture<?> scheduledFuture = scheduleAtFixedRate.scheduleAtFixedRate(
//                    task, 0, 1000 * writeRulesDTO.getPeriod(), TimeUnit);

//            if(periodType == 0){
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(task, 2000, 1000L * writeRulesDTO.getPeriod());
            scheduledFutureCache.put(cacheKey + keyNameId, timer);
//            }
//            else {
//                //随机周期调度
//                scheduleNext(1000L,1000L * writeRulesDTO.getPeriod(),task);
//                randomScheduler = new Timer("RandomScheduler", true);
//                scheduledFutureCache.put(cacheKey + keyNameId, randomScheduler);
//            }

            fastWriteCache.put(cacheKey + keyNameId, writeTagData);


        } catch (Exception e) {
            if (writeTagData != null) {
                writeTagData.stopAll();
            }
            e.printStackTrace();
            return CommonResult.error(500, "执行写入规则出错");
        }

        return CommonResult.success("执行写入规则成功");
    }

//    // 随机数生成器
//    private Timer randomScheduler = new Timer("RandomScheduler", true);
//    private void scheduleNext(long delayMinMs, long delayMaxMs, TimerTask task) {
////        long delay = 1000 + random.nextInt(10_000); // 1秒 ~ 10.999秒（若要严格 1~10秒，则用 nextInt(9000)+1000）
//        long delay = RandomUtil.randomLong(delayMinMs,delayMaxMs);
//        // 更精确的 1~10秒（含）：
//        // long delay = 1000 + random.nextInt(9001); // 1000 ~ 10000 ms
//
//        randomScheduler.schedule(new TimerTask() {
//            @Override
//            public void run() {
//                try {
//                    // 执行你的任务逻辑
//                    task.run();
//                    System.out.println("任务执行: " + DateTime.now());
//                }catch (Exception ex){
//                    ex.printStackTrace();
//                }finally {
//                    // 无论成功失败，都调度下一次（可根据需要加异常处理）
//                    scheduleNext(delayMinMs,delayMaxMs,task);
//                }
//            }
//        }, delay);
//    }

    /**
     * 判断队列里面是否为空
     *
     * @param list
     * @return
     */
    private boolean checkListIsEmpty(List<BlockingQueue<String>> list) {
        boolean result = true;
        for (BlockingQueue<String> dto : list) {
            if (!dto.isEmpty()) {
                result = false;
                break;
            }
        }
        return result;
    }

    public int getQueueId(String line, String tablePre, FastWriteTagData fastWriteTagData, String keyNameId) {
//        String suffixNumber = line.substring(0, line.indexOf(',')).split("_")[1]; // For example: TAG_101
        String suffixNumber = line.substring(0, line.indexOf(',')).replace(tablePre, ""); // For example: TAG_101
        return Integer.parseInt(suffixNumber) % fastWriteTagData.getTaskQueues(keyNameId).size();
    }

    private void fillTdConfigDTO(WriteRulesDto writeRulesDTO, TDConfigDto tdConfigDto) {
        tdConfigDto.setIp(writeRulesDTO.getCreateTableDto().gettDengineConfigDto().getHost());
        tdConfigDto.setPort(writeRulesDTO.getCreateTableDto().gettDengineConfigDto().getPort());
        tdConfigDto.setDbName(writeRulesDTO.getCreateTableDto().gettDengineConfigDto().getName());
        tdConfigDto.setUsername(writeRulesDTO.getCreateTableDto().gettDengineConfigDto().getUsername());
        tdConfigDto.setPassword(writeRulesDTO.getCreateTableDto().gettDengineConfigDto().getPassword());
        tdConfigDto.setVgroups(writeRulesDTO.getCreateTableDto().gettDengineConfigDto().getVgroups());
        tdConfigDto.setBuffer(writeRulesDTO.getCreateTableDto().gettDengineConfigDto().getBuffer());
        tdConfigDto.setTablePre(writeRulesDTO.getCreateTableDto().getPrefix());
        tdConfigDto.setWriteTaskCount(writeRulesDTO.getThreadCount());
        tdConfigDto.setReadTaskCount(1);
        tdConfigDto.setTableIndex(writeRulesDTO.getIndex());
        tdConfigDto.setTableCount(writeRulesDTO.getTableCount());
    }

    /**
     * 停止模拟数据写入
     *
     * @param createTableDto
     * @return
     */
    public CommonResult<String> stopTDengineWrite(CreateTableDto createTableDto, String keyNameId) {
        try {
            FastWriteTagData writeTagData = fastWriteCache.get(this.cacheKey + keyNameId);
            if (writeTagData != null) {
                writeTagData.stopAll(this.cacheKey + keyNameId);
                fastWriteCache.remove(cacheKey + keyNameId);
                Timer timer = scheduledFutureCache.get(this.cacheKey + keyNameId);
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                    scheduledFutureCache.remove(this.cacheKey + keyNameId);
                }
            }
            ;
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.error(500, "停止任务失败");
        }
        return CommonResult.success("取消任务成功");
    }

    public CommonResult<Integer> getTDengineWriteStatus(CreateTableDto createTableDto, String keyNameId) {
        int code = fastWriteCache.get(this.cacheKey + keyNameId) == null ? 0 : 1;
        return CommonResult.success(code);
    }

    /**
     * 创建超级表
     *
     * @param host
     * @param port
     * @param username
     * @param password
     * @param dbName
     * @return
     */
    public Boolean addSuperTable(String host, int port, String username, String password, String dbName) {
        Boolean result = false;
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(host, port, username, password, "");
            tdEngineDao.useDb(dbName);
            tdEngineDao.createSupTableAll();
            result = true;
        } catch (Exception e) {
            logger.error("创建超级表失败", e);
            result = false;
        }

        return result;
    }

    /**
     * 创建自定义超级表
     *
     * @param dbConfig 数据库配置
     * @param tableDto 表格配置
     * @return
     */
    public boolean addCustomSuperTable(DBConfig dbConfig, TableDto tableDto) throws Exception {
        boolean result = false;
        Table table = getTableByTableDto(tableDto);
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                    dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
            tdEngineDao.createSupTable(table);
            result = true;
        } catch (Exception e) {
            logger.error("创建超级表失败", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return result;
    }

    public TableDto getTableStructure(CustomTableDto customTableDto) throws Exception {
        DBConfig dbConfig = customTableDto.getDbConfig();
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                    dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
            return tdEngineDao.getTableStructure(dbConfig.getDbName(), customTableDto.getTableDto().getName());
        } catch (Exception e) {
            logger.error("创建超级表失败", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
    }

    public boolean addCustomTable(DBConfig dbConfig, TableDto tableDto) {
        boolean result = false;
        Table table = getTableByTableDto(tableDto);
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                    dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
            tdEngineDao.useDb(dbConfig.getDbName());
            tdEngineDao.createTable(table);
            result = true;
        } catch (Exception e) {
            logger.error("创建普通表失败", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return result;
    }

    public boolean addChildTable(DBConfig dbConfig, TableDto tableDto) throws Exception {
        boolean result = false;
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                    dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
            HashMap<String, Object> tagValues = new HashMap<>();
            List<ColumnDto> columnDtos = tableDto.getTagsInfo();
            for (ColumnDto columnDto : columnDtos) {
                String type = columnDto.getType();
                TdengineDataType tdengineDataType = TdengineDataType.getTdengineDataType(type);
                String columnName = columnDto.getName();
                String value = columnDto.getValue();
                if (tdengineDataType != null && tdengineDataType.isNumber()) {
                    tagValues.put(columnName, TypeUtils.convertStringToType(value, tdengineDataType.getClassName()));
                } else {
                    tagValues.put(columnName, value);
                }
            }
            tdEngineDao.createTable(tableDto.getSupName(), tableDto.getName(), tagValues, dbConfig.getDbName());
            result = true;
        } catch (Exception e) {
            logger.error("创建子表失败");
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return result;
    }

    /**
     * 将前端发送的表格数据转为Table
     *
     * @param tableDto 前端发送的创建表格的类型
     * @return Table类型
     */
    public Table getTableByTableDto(TableDto tableDto) {
        Table table = new Table();
        table.setTableName(tableDto.getName());
        LinkedHashMap<String, String> columns = new LinkedHashMap<>();
        LinkedHashMap<String, String> tags = new LinkedHashMap<>();
        List<ColumnDto> columnsInfo = tableDto.getColumnsInfo();
        List<ColumnDto> tagsInfo = tableDto.getTagsInfo();
        for (ColumnDto columnDto : columnsInfo) {
            StringBuffer type = new StringBuffer(columnDto.getType());
            if (columnDto.getIsLength()) {
                type.append("(").append(columnDto.getLength()).append(")");
            }
            columns.put(columnDto.getName(), type.toString());
        }
        for (ColumnDto tagDto : tagsInfo) {
            StringBuffer type = new StringBuffer(tagDto.getType());
            if (tagDto.getIsLength()) {
                type.append("(").append(tagDto.getLength()).append(")");
            }
            if (StringUtils.isNotBlank(tagDto.getName())) {
                tags.put(tagDto.getName(), type.toString());
            }
        }
        table.setTags(tags);
        table.setColumns(columns);
        return table;
    }

    /**
     * 删除表格
     *
     * @param dbConfig  数据库配置信息
     * @param tableName 表格名称
     * @return 是否删除成功
     */
    public boolean deleteTable(DBConfig dbConfig, String tableName) throws Exception {
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                    dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
            tdEngineDao.useDb(dbConfig.getDbName());
            tdEngineDao.dropTable(tableName);
        } catch (Exception e) {
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return true;
    }

    /**
     * @param operation 操作类型
     *                  1 新增字段
     *                  2 删除字段
     *                  3 修改字段长度
     *                  4 修改字段名称 只允许普通表修改
     *                  5 新增标签
     *                  6 删除标签
     *                  7 修改标签长度
     *                  8 重命名标签
     */
    public TableDto alterTable(DBConfig dbConfig, ColumnVo columnVo, String tableName, TdengineEnums fieldType, int operation, TdengineEnums tableType) throws Exception {
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                    dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
            tdEngineDao.useDb(dbConfig.getDbName());
            switch (operation) {
                case 1:
                case 5:
                    if ("STABLE".equals(tableType.getName())) {
                        tdEngineDao.addColumnSTable(tableName, dbConfig.getDbName(), columnVo, fieldType);
                    } else {
                        tdEngineDao.addColumnTable(tableName, dbConfig.getDbName(), columnVo);
                    }
                    break;
                case 2:
                case 6:
                    if ("STABLE".equals(tableType.getName())) {
                        tdEngineDao.dropColumnSTable(tableName, dbConfig.getDbName(), columnVo, fieldType);
                    } else {
                        tdEngineDao.dropColumnTable(tableName, dbConfig.getDbName(), columnVo);
                    }
                    break;
                case 3:
                case 7:
                    if ("STABLE".equals(tableType.getName())) {
                        tdEngineDao.modifyColumnSTable(tableName, dbConfig.getDbName(), columnVo, fieldType);
                    } else {
                        tdEngineDao.modifyColumnTable(tableName, dbConfig.getDbName(), columnVo);
                    }
                    break;
                case 4:
                    tdEngineDao.modifyColumnNameTable(tableName, dbConfig.getDbName(), columnVo);
                    break;
                case 8:
                    tdEngineDao.modifyTagNameSTable(tableName, dbConfig.getDbName(), columnVo);
                    break;
            }
            return tdEngineDao.getTableStructure(dbConfig.getDbName(), tableName);
        } catch (Exception e) {
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
    }

    /**
     * 创建数据库
     *
     * @param dbConfig 数据库连接配置
     * @return 返回结果
     * @throws Exception 异常
     */
    public boolean createDatabase(DBConfig dbConfig) throws Exception {
        try {
            TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                    dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
            tdEngineDao.createDatabase(dbConfig.getDbName());
            return true;
        } catch (Exception e) {
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
    }

    /**
     * 批量查询测点历史数据
     *
     * @param queryHisDataInput
     * @return
     */
    public Map<String, List<TagData>> batchQueryHistoryData(QueryHisDataInput queryHisDataInput) {
        Map<String, List<TagData>> result = new HashMap<>();
        DBConfig dbConfig = queryHisDataInput.getDbConfig();
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        try {
            tdEngineDao.useDb(queryHisDataInput.getDbConfig().getDbName());
            List<String> nameList = queryHisDataInput.getNameList();
            System.out.println("开始查询");
            long d1 = System.currentTimeMillis();
            for (String name : nameList) {
                queryHisDataInput.setName(name);
                PageResult<TagData> tagData = tdEngineDao.queryHistoryData(queryHisDataInput);
                if (tagData != null) {
                    List<TagData> tempList = tagData.getList();
                    result.put(name, tempList);
                }
            }
            long d2 = System.currentTimeMillis();
            System.out.println("获取历史值时间：" + (d2 - d1) + "ms");
        } catch (Exception e) {
            logger.error("查询历史数据失败", e);
        }

        return result;
    }

    /**
     * 获取nodes信息
     */
    public List<List<String>> getNodesInfo(DBConfig dbConfig, String type) throws Exception {
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        List<List<String>> result = null;
        try {
            switch (type) {
                case "mnodes":
                    result = tdEngineDao.getMNodesInfo();
                    break;
                case "qnodes":
                    result = tdEngineDao.getQNodesInfo();
                    break;
                default:
                    result = tdEngineDao.getDNodesInfo();
            }
        } catch (Exception e) {
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return result;
    }

    public boolean addNode(DBConfig dbConfig, String type, String dnodeEndpoint, String dNodeId) throws Exception {
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        try {
            switch (type) {
                case "dnodes":
                    tdEngineDao.addDNode(dnodeEndpoint);
                    break;
                case "mnodes":
                    tdEngineDao.addMNode(dNodeId);
                    break;
                case "qnodes":
                    tdEngineDao.addQNode(dNodeId);
                    break;
            }
        } catch (Exception e) {
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return true;
    }

    public Boolean deleteNode(DBConfig dbConfig, String type, String dNodeId) throws Exception {
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        try {
            switch (type) {
                case "dnodes":
                    tdEngineDao.dropDNode(dNodeId);
                    break;
                case "mnodes":
                    tdEngineDao.dropMNode(dNodeId);
                    break;
                case "qnodes":
                    tdEngineDao.dropQNode(dNodeId);
                    break;
            }
        } catch (Exception e) {
            logger.error(e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return true;
    }

    public PageResult<List<String>> getSlowSqlByPage(SlowSqlParamDto slowSqlParamDto) {
        DBConfig dbConfig = slowSqlParamDto.getDbConfig();
        PageParam pageParam = slowSqlParamDto.getPageParam();
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        PageResult<List<String>> pageResult = new PageResult<>();
        try {
            int offset = (pageParam.getPageNo() - 1) * pageParam.getPageSize();
            List<List<String>> totalList = tdEngineDao.getSlowSqlCountAndData(
                    slowSqlParamDto.getStartTime(),
                    slowSqlParamDto.getEndTime(),
                    slowSqlParamDto.getInfoConsumeTimeMin(),
                    slowSqlParamDto.getInfoConsumeTimeMax(),
                    slowSqlParamDto.getIsFilterRepeated(),
                    pageParam.getPageSize(),
                    offset
            );
            int count = Integer.parseInt(totalList.get(1).getFirst());
            totalList.removeFirst();
            totalList.removeFirst();
            pageResult.setTotal((long) count);
            pageResult.setList(totalList);
        } catch (Exception e) {
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return pageResult;
    }

    public PageResult<List<String>> getStatisticalSlowSqlByPage(SlowSqlParamDto slowSqlParamDto) {
        DBConfig dbConfig = slowSqlParamDto.getDbConfig();
        PageParam pageParam = slowSqlParamDto.getPageParam();
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        PageResult<List<String>> pageResult = new PageResult<>();
        try {
            int limit = pageParam.getPageSize();
            int offset = (pageParam.getPageNo() - 1) * limit;
            List<List<String>> data = tdEngineDao.getStatisticSlowSqlInfoByPage(
                    slowSqlParamDto.getStartTime(),
                    slowSqlParamDto.getEndTime(),
                    limit, offset);
            List<String> countRow = data.get(1);
            pageResult.setTotal(Long.valueOf(countRow.getFirst()));
            data.removeFirst();
            data.removeFirst();
            pageResult.setList(data);
        } catch (Exception e) {
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return pageResult;
    }

    /**
     * 修改子表的描述
     * @param dbConfig 数据库
     * @param tagDescMap 测点名
     * ALTER TABLE tb_name SET TAG tag_name=new_tag_value;
     * select tag_value from information_schema.ins_tags where db_name = ? and table_name in (?);
     */
//    public void updateTagDesc(DBConfig dbConfig, HashMap<String, String> tagDescMap) throws Exception {
//        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
//                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
//        //需要修改的总的数据条数
//        int updateCount = tagDescMap.size();
//        List<String> tableNames = new ArrayList<>(2000);
//        String dbName = dbConfig.getDbName();
//        String searchSql = "select table_name,tag_value from information_schema.ins_tags where db_name = '%s' and table_name in ('%s')";
//        Connection connection = null;
//        Statement searchStatement = null;
//        Statement updateStatement = null;
//        ResultSet resultSet = null;
//        String regex = "tagDesc:'(.*?)'";
//        Pattern pattern = Pattern.compile(regex);
//        String updateSql = "ALTER TABLE %s.%s SET TAG ti=\"%s\"";
//        try{
//            int index = 0;
//            //最后剩余量
//            int surplusCount = updateCount % 2000;
//            //批量执行的次数
//            int executeCount = updateCount / 2000;
//            connection = tdEngineDao.getConnection();
//            searchStatement = connection.createStatement();
//            updateStatement = connection.createStatement();
//            int currentIndex = 0;
//            for(String tableName : tagDescMap.keySet()){
//                tableNames.add(tableName);
//                index++;
//                if(index == 2000 || (currentIndex == executeCount && index == surplusCount)){
//                    //查询
//                    String sql = String.format(searchSql,dbName,String.join("','",tableNames));
//                    resultSet = searchStatement.executeQuery(sql);
//                    boolean flag = false;
//                    while(resultSet.next()){
//                        String tagName = resultSet.getString("table_name");
//                        String tagValue = resultSet.getString("tag_value");
//                        if(tagValue != null && tagValue.indexOf("tagDesc")>0){
//                            Matcher matcher = pattern.matcher(tagValue);
//                            String newTagDesc = tagDescMap.get(tagName);
//                            String newDesc = matcher.replaceAll("tagDesc:'" + newTagDesc + "'");
////                        TagInfo tagInfo = new TagInfo();
////                        tagInfo.setTagName(tagName);
////                        tagInfo.setTagDesc(newTagDesc);
//                            String updateExecuteSql = String.format(updateSql,dbName,tagName,newDesc);
//                            updateStatement.addBatch(updateExecuteSql);
//                            flag = true;
//                        }
//                    }
//                    if(flag){
//                        updateStatement.executeBatch();
//                        updateStatement.clearBatch();
//                    }
//                    tableNames.clear();
//                    index = 0;
//                    resultSet.close();
//                    currentIndex++;
//                }
//            }
//            tagDescMap.clear();
//        }catch (Exception e){
//            logger.error("更新报错",e);
//            throw ServiceExceptionUtil.exception0(500, e.getMessage());
//        }finally {
//            if(searchStatement != null){
//                searchStatement.close();
//            }
//            if(updateStatement != null){
//                updateStatement.close();
//            }
//            if(connection != null){
//                connection.close();
//            }
//        }
//    }

    /**
     * 修改子表的tn
     *
     * @param dbConfig 数据库
     *                 ALTER TABLE tb_name SET TAG tag_name=new_tag_value;
     *                 select tag_value from information_schema.ins_tags where db_name = ? and table_name in (?);
     */
    public void updateTagTn(DBConfig dbConfig, HashMap<String, String> tagTnMap) throws Exception {
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        String dbName = dbConfig.getDbName();
        Connection connection = null;
        Statement updateStatement = null;
        String updateSql = "ALTER TABLE %s.%s SET TAG tn=\"%s\"";
        try {
            int index = 0;
            int batchSize = 100;
            connection = tdEngineDao.getConnection();
            connection.setAutoCommit(false);
            updateStatement = connection.createStatement();
            Iterator<String> its = tagTnMap.keySet().iterator();
            while (its.hasNext()) {
                String tbname = its.next();
                String updateExecuteSql = String.format(updateSql, dbName, tbname, tagTnMap.get(tbname));
                updateStatement.addBatch(updateExecuteSql);
                if (++index % batchSize == 0) {
                    updateStatement.executeBatch();
                    updateStatement.clearBatch();
                    Thread.sleep(100);
                }
            }
            updateStatement.executeBatch();
            connection.commit();

        } catch (Exception e) {
            logger.error("更新报错", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        } finally {
            if (updateStatement != null) {
                updateStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }

    /**
     * 修改子表的ti
     *
     * @param dbConfig 数据库
     *                 ALTER TABLE tb_name SET TAG tag_name=new_tag_value;
     *                 select tag_value from information_schema.ins_tags where db_name = ? and table_name in (?);
     */
    public void updateTagTi(DBConfig dbConfig, HashMap<String, String> tagTnMap) throws Exception {
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        String dbName = dbConfig.getDbName();
        Connection connection = null;
        Statement updateStatement = null;
        String updateSql = "ALTER TABLE %s.%s SET TAG ti=\"%s\"";
        try {
            int index = 0;
            connection = tdEngineDao.getConnection();
            updateStatement = connection.createStatement();
            Iterator<String> its = tagTnMap.keySet().iterator();
            while (its.hasNext()) {
                String tbname = its.next();
                String updateExecuteSql = String.format(updateSql, dbName, tbname, tagTnMap.get(tbname));
                updateStatement.addBatch(updateExecuteSql);
            }
            updateStatement.executeBatch();
            updateStatement.clearBatch();

        } catch (Exception e) {
            logger.error("更新报错", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        } finally {
            if (updateStatement != null) {
                updateStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }

    public Boolean initTiTable(String host, int port, String username, String password, String dbName) {
        TDEngineDao tdEngineDao = getTDEngineDao(host, port, username, password, dbName);
        //需要修改的总的数据条数
        Connection connection = null;
        Statement searchStatement = null;
        Statement updateStatement = null;
        String updateSql = "ALTER TABLE %s.%s SET TAG ti=\"%s\"";
        try {
            int index = 0;
            connection = tdEngineDao.getConnection();
            searchStatement = connection.createStatement();
            updateStatement = connection.createStatement();
            String searchSql = "select table_name,tag_value from information_schema.ins_tags where db_name = '" + dbName + "' and tag_name = 'ti'";
            try (ResultSet resultSet = searchStatement.executeQuery(searchSql)) {
                //rs需要关闭
                int size = 0;
                while (resultSet.next()) {
                    String tbname = resultSet.getString(1);
                    String tiInfo = resultSet.getString(2);
                    TagInfo tagInfo = JSON.parseObject(tiInfo, TagInfo.class);
                    if (tagInfo.getPointNum() != 2) {
                        tagInfo.setMaxValue(100.0);
                        tagInfo.setPointNum(2);
                        tagInfo.setMinValue(0.0);
                        String updateExecuteSql = String.format(updateSql, dbName, tbname, tagInfo.toString());
                        updateStatement.addBatch(updateExecuteSql);
                        size++;
                    }
                }
                System.out.println("待更新的数量:" + size);
                if (size > 0) {
                    updateStatement.executeBatch();
                    updateStatement.clearBatch();
                }
            } catch (Exception e) {
                logger.error("查询报错", e);
                throw ServiceExceptionUtil.exception0(500, e.getMessage());
            }
        } catch (Exception e) {
            logger.error("更新报错", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        } finally {
            if (updateStatement != null) {
                try {
                    updateStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (searchStatement != null) {
                try {
                    searchStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return true;
    }

    public Boolean initTnTable(String host, int port, String username, String password, String dbName) {
        TDEngineDao tdEngineDao = getTDEngineDao(host, port, username, password, dbName);
        //需要修改的总的数据条数
        Connection connection = null;
        Statement searchStatement = null;
        Statement updateStatement = null;
        String updateSql = "ALTER TABLE %s.%s SET TAG tn=\"%s\"";
        try {
            int index = 0;
            Map<Integer, String> nameMap = SyzTypeUtils.initMap();
            connection = tdEngineDao.getConnection();
            searchStatement = connection.createStatement();
            updateStatement = connection.createStatement();
            String searchSql = "show tables;";
            try (ResultSet resultSet = searchStatement.executeQuery(searchSql)) {
//            ResultSet resultSet = searchStatement.executeQuery(searchSql);
                while (resultSet.next()) {
                    String tbname = resultSet.getString(1);
                    TagInfo tagInfo = new TagInfo();
                    tagInfo.setTagType(TagType.FLOAT);
                    tagInfo.setTagName(tbname);
                    String val = getTnName(tbname, nameMap);
                    String updateExecuteSql = String.format(updateSql, dbName, tbname, val);
                    updateStatement.addBatch(updateExecuteSql);
                }

                updateStatement.executeBatch();
                updateStatement.clearBatch();
            } catch (Exception e) {
                logger.error("查询报错", e);
                throw ServiceExceptionUtil.exception0(500, e.getMessage());
            }
        } catch (Exception e) {
            logger.error("更新报错", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        } finally {
            if (updateStatement != null) {
                try {
                    updateStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (searchStatement != null) {
                try {
                    searchStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return true;
    }

    public Boolean convertTnTable(String host, int port, String username, String password, String dbName) {
        TDEngineDao tdEngineDao = getTDEngineDao(host, port, username, password, dbName);
        //需要修改的总的数据条数
        Connection connection = null;
        Statement searchStatement = null;
        Statement updateStatement = null;
        String updateSql = "ALTER TABLE %s.%s SET TAG tn=\"%s\"";
        try {

            Map<Integer, String> nameMap = SyzTypeUtils.initMap();
            connection = tdEngineDao.getConnection();
            searchStatement = connection.createStatement();
            updateStatement = connection.createStatement();
            String searchSql = "show tables;";
            try (ResultSet resultSet = searchStatement.executeQuery(searchSql)) {
                while (resultSet.next()) {
                    String tbname = resultSet.getString(1);
                    TagInfo tagInfo = new TagInfo();
                    tagInfo.setTagType(TagType.FLOAT);
                    tagInfo.setTagName(tbname);
                    String val = getTnName(tbname, nameMap);
                    String updateExecuteSql = String.format(updateSql, dbName, tbname, val);
                    updateStatement.addBatch(updateExecuteSql);
                }

//            for(int i =1000000;i<1100000;i++){
//                String val = "aalm3";
//                String tbname = "float_aalm3_"+i;
//                String updateExecuteSql = String.format(updateSql,dbName,tbname,val);
//                updateStatement.addBatch(updateExecuteSql);
//            }
                updateStatement.executeBatch();
                updateStatement.clearBatch();
            } catch (Exception e) {
                logger.error("查询报错", e);
                throw ServiceExceptionUtil.exception0(500, e.getMessage());
            }
        } catch (Exception e) {
            logger.error("更新报错", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        } finally {
            if (updateStatement != null) {
                try {
                    updateStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (searchStatement != null) {
                try {
                    searchStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return true;
    }

    private String getTnName(String tbname, Map<Integer, String> nameMap) {
        String val = "空场站";
        if (StringUtils.isNotBlank(tbname) && nameMap != null) {
            String[] arr = tbname.split("_");
            if (arr.length > 1) {
                try {
                    int index = Integer.parseInt(arr[1]);
                    if (nameMap.containsKey(index)) {
                        val = nameMap.get(index);
                    }
                } catch (Exception e) {
                    logger.error(tbname + "转换数字错误", e);
                }

            }
        }
        return val;
    }

    /**
     * 导出历史数据
     *
     * @param queryHisDataInput
     * @return
     */
    public Workbook exportData(QueryHisDataInput queryHisDataInput) {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Data");
        // 创建标题行
        Row titleRow = sheet.createRow(0);
        Cell titleCell0 = titleRow.createCell(0);
        titleCell0.setCellValue("时间");
        Cell titleCell1 = titleRow.createCell(1);
        titleCell1.setCellValue("值");

        DBConfig dbConfig = queryHisDataInput.getDbConfig();
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig.getHost(), dbConfig.getPort(),
                dbConfig.getUsername(), dbConfig.getPassword(), dbConfig.getDbName());
        try {
            tdEngineDao.useDb(queryHisDataInput.getDbConfig().getDbName());
            queryHisDataInput.setPageNum(1);
            queryHisDataInput.setPageSize(500000);
            //返回的最大数据设置为50w
            PageResult<TagData> result = tdEngineDao.queryHistoryData(queryHisDataInput);
            List<TagData> data = result.getList();
            if (data != null && data.size() > 0) {
                int downloadCount = 0;
                for (TagData tagData : data) {
                    Row row = sheet.createRow(downloadCount + 1);
                    Cell cell0 = row.createCell(0);
                    Cell cell1 = row.createCell(1);
                    cell0.setCellValue(new DateTime(tagData.getTs()).toString("yyyy-MM-dd HH:mm:ss"));
                    cell1.setCellValue(tagData.getV());
                    downloadCount++;
                }
            }
        } catch (Exception e) {
            logger.error("查询历史数据失败", e);
        }

        return workbook;
    }

    public void deleteDataByPeriod(String host, int port, String username, String password, String dbName, String tbname, long timestamp) throws SQLException {
        TDEngineDao tdEngineDao = getTDEngineDao(host, port, username, password, dbName);
        try {
            tdEngineDao.useDb(dbName);
            tdEngineDao.deleteDataByPeriod(dbName, tbname, timestamp);
        } catch (SQLException e) {
            logger.error("获取表失败", e);
        }
    }

    public Boolean updateTsValue(String data) throws Exception {
        JSONObject jsonObject = JSONObject.parseObject(data);
        DBConfig dbConfig = JSONObject.parseObject(jsonObject.getString("dbConfig"), DBConfig.class);
        TagData tagData = JSONObject.parseObject(jsonObject.getString("tagData"), TagData.class);
        TagInfo tagInfo = JSONObject.parseObject(jsonObject.getString("tagInfo"), TagInfo.class);
        TDEngineDao tdEngineDao = getTDEngineDao(dbConfig);
        try {
            tdEngineDao.useDb(dbConfig.getDbName());
            tdEngineDao.insertData(tagInfo.getTagName(), Collections.singletonList(tagData));
        } catch (SQLException e) {
            logger.error("更新表格值失败", e);
            throw ServiceExceptionUtil.exception0(500, e.getMessage());
        }
        return true;
    }
}
